﻿// -----------------------------------------------------------------------
// <copyright file="Player.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Exc2
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class Player
    {
        private string m_playerName;
        private int m_points;
        private char m_playerSymbol;
        private List<CheckerCell> m_playerPawns;
        private List<CheckersMove> m_availableMoves;
        private bool m_hasEatingMoves;

        public Player(char i_playerSymbol)
        {
            m_points = 0;
            m_playerName = null;
            m_playerPawns = null;
            m_playerSymbol = i_playerSymbol;
            m_availableMoves = new List<CheckersMove>();
            m_hasEatingMoves = false;
        }

        public void InitializePlayerPawnsArray(int i_gameBoardSize)
        {
            int linesToFill = (i_gameBoardSize / 2) - 1;
            m_playerPawns = new List<CheckerCell>();

            int currentPlaceInList = 0;

            if (m_playerSymbol == 'O')
            {
                for (int i = 0; i < linesToFill; ++i)
                {
                    int j;
                    if (i % 2 == 0)
                    {
                        j = 1;
                    }
                    else
                    {
                        j = 0;
                    }

                    for (; j < i_gameBoardSize; j += 2)
                    {
                        m_playerPawns.Insert(currentPlaceInList, new CheckerCell());
                        m_playerPawns[currentPlaceInList].CellColumn = (char)('A' + j);
                        m_playerPawns[currentPlaceInList].CellRow = (char)('a' + i);
                        m_playerPawns[currentPlaceInList++].PawnSymbol = 'O';
                    }
                }
            }
            else
            {
                for (int i = linesToFill + 2; i < i_gameBoardSize; ++i)
                {
                    int j;
                    if (i % 2 == 0)
                    {
                        j = 1;
                    }
                    else
                    {
                        j = 0;
                    }

                    for (; j < i_gameBoardSize; j += 2)
                    {
                        m_playerPawns.Insert(currentPlaceInList, new CheckerCell());
                        m_playerPawns[currentPlaceInList].CellColumn = (char)('A' + j);
                        m_playerPawns[currentPlaceInList].CellRow = (char)('a' + i);
                        m_playerPawns[currentPlaceInList++].PawnSymbol = 'X';
                    }
                }
            }
        }

        public void updatePlayerPawnsArray(CheckersMove i_moveToUpdate)
        {
           foreach(CheckerCell currentPawn in m_playerPawns)
            {
                if (i_moveToUpdate.fromCell.equals(currentPawn))
                {
                    currentPawn.CellColumn = i_moveToUpdate.toCell.CellColumn;
                    currentPawn.CellRow = i_moveToUpdate.toCell.CellRow;
                    break;
                }
            }
        }

        public void RemoveEatenPawn(CheckersMove i_moveToDeletePawnFrom)
        {
            CheckerCell cellToDelete = new CheckerCell();
            int middleColumnIndex, middleRowIndex;
            if ((int)i_moveToDeletePawnFrom.toCell.CellColumn > (int)i_moveToDeletePawnFrom.fromCell.CellColumn)
            {
                middleColumnIndex = 1;
            }
            else
            {
                middleColumnIndex = -1;
            }

            if ((int)i_moveToDeletePawnFrom.toCell.CellRow > (int)i_moveToDeletePawnFrom.fromCell.CellRow)
            {
                middleRowIndex = 1;
            }
            else
            {
                middleRowIndex = -1;
            }

            cellToDelete.CellColumn = (char)((int)i_moveToDeletePawnFrom.fromCell.CellColumn + middleColumnIndex);
            cellToDelete.CellRow = (char)((int)i_moveToDeletePawnFrom.fromCell.CellRow + middleRowIndex);
            foreach (CheckerCell currentPawn in m_playerPawns)
            {
                if (currentPawn.equals(cellToDelete))
                {
                    m_playerPawns.Remove(currentPawn);
                    break;
                }
            } 
        }

        public void VictoryAtrributes(List<CheckerCell> i_losingPlayerPawnsArray)
        {
            m_points = CalculatePoints(m_playerPawns) - CalculatePoints(i_losingPlayerPawnsArray);
        }

        private int CalculatePoints(List<CheckerCell> i_pawnsToCalculate)
        {
            int sumOfPoints = 0;
            foreach (CheckerCell currentPawn in i_pawnsToCalculate)
            {
                if (currentPawn.PawnSymbol == 'X' || currentPawn.PawnSymbol == 'O')
                {
                    sumOfPoints++;
                }
                else
                {
                    sumOfPoints += 4;
                }
            }

            return sumOfPoints;
        }

        public int FindPlaceInPawnArray(CheckerCell i_cellToFind, ref bool i_isMoveLegal)
        {
            int placeOfMoveInArray = 0;
            foreach (CheckerCell currentCell in m_playerPawns)
            {
                if(currentCell.equals(i_cellToFind))
                {
                    break;
                }

                placeOfMoveInArray++;
            }

            if (placeOfMoveInArray >= m_availableMoves.Count)
            {
                i_isMoveLegal = false;
            }

            return placeOfMoveInArray;
        }

        public void ChangePawnSymbolInArray(int i_placeInPawnArray, char i_SymbolToChange)
        {
            m_playerPawns[i_placeInPawnArray].PawnSymbol = i_SymbolToChange;
        }

        public CheckersMove GeneratePlayerMove()
        {
            Random randomMove = new Random();
            int randomMoveIndex = randomMove.Next(0, m_availableMoves.Count - 1);
            if (m_hasEatingMoves)
            {
                while(!m_availbleMoves[randomMoveIndex].isEatingMove)
                {
                    randomMoveIndex = randomMove.Next(0, m_availableMoves.Count - 1);
                }
            }

            CheckersMove computerMove = new CheckersMove(m_availableMoves[randomMoveIndex].MoveSymbol, m_availableMoves[randomMoveIndex].isEatingMove);
            computerMove.fromCell.CellColumn = m_availableMoves[randomMoveIndex].fromCell.CellColumn;
            computerMove.fromCell.CellRow = m_availableMoves[randomMoveIndex].fromCell.CellRow;
            computerMove.toCell.CellColumn = m_availableMoves[randomMoveIndex].toCell.CellColumn;
            computerMove.toCell.CellRow = m_availableMoves[randomMoveIndex].toCell.CellRow;

            return computerMove;
        }

        public string Name
        {
            get
            {
                return m_playerName;
            }

            set
            {
                if (value.Length > 20)
                {
                    throw new TooLongException(value.Length);
                }
                else
                {
                    m_playerName = value;
                }
            }
        }

        public int NumOfPawns
        {
            get
            {
                return m_playerPawns.Count;
            }
        }

        public CheckerCell GetPlayerPawnsCell(int i_requestedCheckerCell)
        {
            return m_playerPawns[i_requestedCheckerCell];
        }

        public List<CheckerCell> GetPlayerPawnsArray()
        {
            return m_playerPawns;
        }

        public List<CheckersMove> GetPlayerAvailableMovesArray()
        {
            return m_availbleMoves;
        }

        public char Symbol
        {
            get
            {
                return m_playerSymbol;
            }
        }

        public List<CheckersMove> m_availbleMoves
        {
            get
            {
                return m_availableMoves;
            }
        }

        public bool HasEatingMoves
        {
            get
            {
                return m_hasEatingMoves;
            }

            set
            {
                m_hasEatingMoves = value;
            }
        }

        public int Points
        {
            get
            {
                return m_points;
            }
        }
    }

    public class TooLongException : Exception
    {
        public TooLongException(int i_nameLength)
            : base("The name length is illegal")
        { 
        }
    }
}